package cn.sky.demo.service.impl;

import cn.sky.demo.domain.entity.Message;
import cn.sky.demo.domain.entity.ReminderTask;
import cn.sky.demo.mapper.MessageDao;
import cn.sky.demo.mapper.UserMapper;
import cn.sky.demo.repository.ReminderTaskDao;
import cn.sky.demo.service.SmsService;
import cn.sky.demo.utils.MessageSendThread;
import cn.sky.demo.utils.SmsClient;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;


import java.io.Serializable;
import java.time.LocalDate;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

@Service
@Slf4j
public class SmsServiceImpl implements SmsService{
    
    @Autowired
    private ReminderTaskDao reminderTaskDao;

    @Autowired
    private MessageDao messageDao;

    @Autowired
    private SmsClient smsClient;  // 短信发送客户端
    
    // 定时任务，每天检查需要发送提醒的任务
    @Override
    //@Scheduled(cron = "0/10 * * * * ?")  // 每天上午9点执行
    public void sendDailyReminders() {
        log.info("定时任务进行中sendDailyReminders.......");
        List<ReminderTask> tasks = reminderTaskDao.findTasksForToday();
        
        for (ReminderTask task : tasks) {
            try {
                // 发送短信
                String result = smsClient.sendSms(task.getPhone(), task.getMessage());
                
                // 记录发送结果
                recordSmsSend(task.getId(), task.getPhone(), task.getMessage(), result);
                
                // 更新下次提醒日期
                LocalDate nextDate = task.getNextRemindDate().plusDays(task.getIntervalDays());
                reminderTaskDao.updateNextRemindDate(task.getId(), nextDate);
                
            } catch (Exception e) {
                // 记录发送失败
                recordSmsSend(task.getId(), task.getPhone(), task.getMessage(), "FAILED: " + e.getMessage());
            }
        }
    }
    
    private void recordSmsSend(Long taskId, String phone, String message, String result) {
        reminderTaskDao.recordSmsSend(taskId, phone, message, result);
    }
    
    @Override
    public void createReminderTask(ReminderTask task) {
        // 设置下次提醒日期为开始日期
        task.setNextRemindDate(task.getStartDate());
        reminderTaskDao.insertTask(task);
    }
    
    @Override
    public void cancelReminder(Long taskId) {
        reminderTaskDao.deactivateTask(taskId);
    }
    /**
     * 推送消息 APP、短信
     * @param message
     * @throws Exception
     */
    @Override
    public void sendMsg(Message message) throws Exception{
        try {
            log.info("send message start...");
            long startTime = System.currentTimeMillis();
            BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(20000);
            ThreadPoolExecutor executors = new ThreadPoolExecutor(5, 6, 60000, TimeUnit.SECONDS, queue);

            //要推送的用户总数
            int count = filterPhonesCount(message);
            log.info("message all count=>{}",count);
            //初始每个线程处理的用户数量
            final int eveLength = 2000;
            //计算处理所有用户需要的线程数量
            int eveBlocks = count / eveLength + (count % eveLength != 0 ? 1 : 0);
            log.info("need thread's count=>{}",eveBlocks);
            //线程计数器
            CountDownLatch doneSignal = new CountDownLatch(eveBlocks);

            //开启线程处理
            int doneCount = 0;
            for (int page = 0; page < eveBlocks; page++) { /* blocks太大可以再细分重新调度 */
                MessageSendThread ms = new MessageSendThread(new MessageDao(){
                    @Override
                    public Map<String, Object> filterPhones(Message message, Integer currentIndex, Integer rows) {
                        return null;
                    }

                    @Override
                    public Message getMessageById(Long id) {
                        return null;
                    }

                    @Override
                    public List<Message> getAllMessages() {
                        return null;
                    }

                    @Override
                    public boolean updateMessageStatus(Message message) {
                        return false;
                    }

                    @Override
                    public boolean saveMessage(Message message) {
                        return false;
                    }

                    @Override
                    public List<Map<String, Object>> selectTargetCustomersByBlock(String receiverGroupType, int offset, int limit) {
                        return null;
                    }

                    @Override
                    public Integer countTargetCustomers(String receiverGroupType) {
                        return null;
                    }

                    @Override
                    public int insert(Message entity) {
                        return 0;
                    }

                    @Override
                    public int deleteById(Serializable id) {
                        return 0;
                    }

                    @Override
                    public int deleteById(Message entity) {
                        return 0;
                    }

                    @Override
                    public int deleteByMap(Map<String, Object> columnMap) {
                        return 0;
                    }

                    @Override
                    public int delete(Wrapper<Message> queryWrapper) {
                        return 0;
                    }

                    @Override
                    public int deleteBatchIds(Collection<?> idList) {
                        return 0;
                    }

                    @Override
                    public int updateById(Message entity) {
                        return 0;
                    }

                    @Override
                    public int update(Message entity, Wrapper<Message> updateWrapper) {
                        return 0;
                    }

                    @Override
                    public Message selectById(Serializable id) {
                        return null;
                    }

                    @Override
                    public List<Message> selectBatchIds(Collection<? extends Serializable> idList) {
                        return null;
                    }

                    @Override
                    public List<Message> selectByMap(Map<String, Object> columnMap) {
                        return null;
                    }

                    @Override
                    public Long selectCount(Wrapper<Message> queryWrapper) {
                        return null;
                    }

                    @Override
                    public List<Message> selectList(Wrapper<Message> queryWrapper) {
                        return null;
                    }

                    @Override
                    public List<Map<String, Object>> selectMaps(Wrapper<Message> queryWrapper) {
                        return null;
                    }

                    @Override
                    public List<Object> selectObjs(Wrapper<Message> queryWrapper) {
                        return null;
                    }

                    @Override
                    public <P extends IPage<Message>> P selectPage(P page, Wrapper<Message> queryWrapper) {
                        return null;
                    }

                    @Override
                    public <P extends IPage<Map<String, Object>>> P selectMapsPage(P page, Wrapper<Message> queryWrapper) {
                        return null;
                    }
                }, message, page + 1, eveLength, doneSignal);
                executors.execute(ms);
                log.info("start thread =>{}",page+1);
                doneCount++;
            }
            doneSignal.await();//等待所有计数器线程执行完
            long endTime = System.currentTimeMillis();
            log.info("send message all thread ends!time(s)=>{}",(startTime-endTime)/1000);
            log.info("all thread count=>{}",doneCount);
        } catch (Exception e) {
            log.error("send message error=>{}",e);
        }
    }
    /**
     * 根据消息条件筛选目标用户数量
     * @param message 消息实体
     * @return 目标用户总数
     */
    private int filterPhonesCount(Message message) {
        try {
            // 调用 DAO 方法获取符合条件的用户总数
            Integer count = reminderTaskDao.countTargetCustomers(message.getReceiverGroupType());
            return count != null ? count : 0;
        } catch (Exception e) {
            log.error("获取目标用户数量失败: {}", e.getMessage(), e);
            return 0;
        }
    }



}
